package com.abc.tacos.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.sql.DataSource;

/**
 * @author Kar
 * @create 2022-04-20 上午10:42
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // 1、使用httpbasic认证的方式
    // @Override
    // protected void configure(HttpSecurity http) throws Exception {
    //     http.httpBasic()//开启httpbasic认证
    //         .and().authorizeRequests().anyRequest().authenticated();//所有请求都需要登录认证才能访问
    //     http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    // }

    // 2、使用表单验证
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests() //允许基于HttpServletRequest使用限制访问
                .antMatchers("/Asuka","/design","/order")
                    //.authenticated() // 其他路径必须验证身份
                    .access("hasRole('USER') || hasRole('MANAGERS')") // 验证角色信息
                //.antMatchers("/", "/home")
                //    .access("permitAll") //不需要身份认证
                .and()
                    .formLogin() // 使用表单登陆
                        .loginPage("/login") // 自定义登陆页面
                        //.permitAll()
                        // .defaultSuccessUrl("/",true)
                .and()
                    .logout()   // 拦截"/logout" post 请求, 清除session数据
                        .logoutSuccessUrl("/")

                // Make H2-Console non-secured; for debug purposes
                // tag::csrfIgnore[]
                .and()
                    .csrf()
                        .ignoringAntMatchers("/h2-console/**")
                // end::csrfIgnore[]

                // Allow pages to be loaded in frames from the same origin; needed for H2-Console
                // tag::frameOptionsSameOrigin[]
                .and()
                    .headers()
                        .frameOptions()
                            .sameOrigin();
                // end::frameOptionsSameOrigin[]
    }

    // 1） 基于内存的用户存储
    //@Override
    //protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    //    auth.inMemoryAuthentication()
    //            .withUser("Kar")
    //                .password("{noop}123456")
    //                .authorities("ROLE_USER")
    //            .and()
    //            .withUser("Eylin")
    //                .password("{noop}654321")
    //                .roles("USER");
    //}


    // 2） 基于JDBC的用户存储
    // @Autowired
    // private DataSource dataSource;
    //
    // @Override
    // protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    //     auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(new BCryptPasswordEncoder());
    // }

/*
    // 3）基于LDAP的用户存储
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.ldapAuthentication()
                // .userSearchBase("ou=people")
                .userSearchFilter("(uid={0})")
                // .groupSearchBase("ou=groups")
                .groupSearchFilter("(member={0})")
                .passwordCompare()
                .passwordEncoder(new BCryptPasswordEncoder())
                .passwordAttribute("userPassword")
                .and()
                .contextSource()
                    // Optional root suffix for the embedded LDAP server.
                    // Default is "dc=springframework,dc=org"
                    .root("dc=taco,dc=com")
                    //.ldif("classpath:schema.ldif") // 默认为 classpath:schema.ldif

                // .userDnPatterns("uid={0},ou=people")
                // .groupSearchBase("ou=groups")
                // .contextSource()
                // // .root("dc=springframework,dc=org")
                // .and()
                // .passwordCompare()
                // .passwordEncoder(new BCryptPasswordEncoder())
                // .passwordAttribute("userPassword")
        ;
    }*/

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder encoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth
                .userDetailsService(userDetailsService)
                // encoder()具有@Bean注解，当调用它时将被拦截，返回容器中它的实例。
                .passwordEncoder(encoder())
        ;
    }
}
